import cgi
import os
import logging
import utils
import datamodel
import urllib

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.api import users

from trip_crud import Trip
from mail_crud import Mail
from area_crud import Area
from hotel_crud import Hotel
from hotel_reservation_crud import HotelReservation
from linksconfig_crud import LinkConfig
from user_crud import AppUser

class Dispatcher(webapp.RequestHandler):

	def __init__(self):
		self.action = None
		self.modelName = None
		self.modelObject = None
		self.modelKey = None
		self.userId = None
		self.isAdmin = None
		self.isAdminData = False

	def post(self):
		logging.info(" POST Dispatcher Request: %s", self.request.url)
		str = None
		for arg in self.request.arguments():
			if self.request.path.endswith("json"):
				str = arg
			logging.info("arg NAME: %s : VALUE %s", arg, self.request.get(arg))
		self.handleRequest(str)
	def get(self):
		logging.info(" GET Dispatcher Request: %s", self.request.url)
		self.handleRequest(self.request.query_string)

	def handleRequest(self, json_input_string):
		currentUser = users.get_current_user()
		if currentUser:
			self.isAdmin = users.is_current_user_admin()
			self.userId=currentUser.user_id()

		self.isAdminData = (self.request.path.find("admin") >0)
		logging.info("IsAdminData: %s", self.isAdminData)
		logging.info("IsAdmin: %s", self.isAdmin)
	
		# parsing the url
    		urlPath = self.request.path
		if urlPath == '/':
			if self.isAdmin:
				self.redirect("/admin/index.html")
			else:
				self.redirect("/index.html")
			return

		logging.info(" Dispatcher Urlpath: %s", urlPath)
		urlDetails = urlPath.rsplit("/")
		try:
			for i in range(len(urlDetails)):
				if urlDetails[i] == "dispatch":
					model = urlDetails[i+1]
					# getting object to work on
					self.modelName = model.lower()
					logging.info('Working on model %s', self.modelName)
					if self.modelName == "trip":
						obj = Trip()
					elif self.modelName == "area":
						obj = Area()
					elif self.modelName == "hotel":
						obj = Hotel()
					elif self.modelName == "linkconfig":
						obj = LinkConfig()
					elif self.modelName == "reservation":
						obj = HotelReservation()
					elif self.modelName == "mail":
						obj = Mail()
					elif self.modelName == "user":
						obj = AppUser()
					else:
						logging.info('This model does not exist. Sending back to main page')
						raise RuntimeError('This model does not exist.')
			
					self.action = urlDetails[i+2]
					actionDetails = self.action.rsplit(".")
					self.action = actionDetails[0]
					# checking the json request for details
					if self.request.path.endswith("json"):
						logging.info("we got a json request")
						if len(urlDetails) > (i+3) :
							# we have a request with a key in in
							jsonUrl = urlDetails[len(urlDetails) -1]
							jsonUrl = jsonUrl.rsplit(".")
							self.modelKey = jsonUrl[0]
							logging.info('Got a JSON request, with key: %s', self.modelKey)
							self.modelObject = db.get(self.modelKey)
							logging.info("retrieved object: %s", str(self.modelObject.key()))
							if not self.isAdminData:
								if (self.modelObject.userId != self.userId):
									raise Exception("No Permissions")
	
						if self.action == "create" or self.action == "update":
							logging.info("checking for object for action %s", self.action)
							# we have a request with an object maybe
							inputStr = urllib.unquote(json_input_string)
							logging.info('Got a JSON request, will decode input: %s', inputStr)
							self.modelObject = obj.decode("json", inputStr, self.modelObject, self)
					break
			logging.info('Model: %s, Action: %s', model, self.action)
			
			# calling the appropriate action
			if self.action == "create":
				logging.info('Calling create action.')
				output = obj.create(self)
			elif self.action == "update":
				logging.info('Calling update action.')
				output = obj.update(self)
			elif self.action == "delete":
				logging.info('Calling delete action.')
				output = obj.delete(self)
			elif self.action == "get":
				logging.info('Getting.')
				output = obj.get(self)
			else:
				logging.info('This action does not exist.')
				raise RuntimeError('This action does not exist.')
			if output:
				outputStr= obj.encode("json", output, self)
			else:
				outputStr= "{}"
			logging.info("Output String: %s",outputStr)
			self.response.out.write(outputStr)

		except Exception, inst:
			logging.error('Error %s', inst)
			self.error(500)
			self.response.out.write(inst)
			return

		

